package lang;

import org.junit.Test;

import java.util.LinkedList;

public class ObjectTest {

    public static class MyObject {
        @Override
        protected void finalize() throws Throwable {
            System.out.println("gc start...");
            Thread.sleep(10000);
            System.out.println("gc end...");
        }
    }

    @Test
    public void finalizeTest() throws InterruptedException {

        MyObject myObject = new MyObject();
        myObject = null;
        System.gc();
        Thread.sleep(5000);
    }

    @Test
    public void waitTest() throws InterruptedException {
        System.out.println("start...");
        synchronized (this) {
            //由于没有唤醒会一直休眠下去
            wait();
        }
        System.out.println("end...");
    }

    @Test
    public void notifyTest() {
        System.out.println("start...");
        synchronized (this) {
            notifyAll();
        }
        System.out.println("end...");
    }

    @Test
    public void waitNotifyTest() throws InterruptedException {

        final LinkedList<Integer> queue = new LinkedList();
        final int maxSize = 2;
        final int maxNum = 5;

        Object producerLock = new Object();
        Object consumerLock = new Object();
        Object showLock = new Object();

        Thread producerThread = new Thread() {

            int num = 0;

            @Override
            public void run() {
                while(num <= maxNum) {
                    try {
                        while (queue.size() >= maxSize) {
                            synchronized (producerLock) {
                                System.out.println("仓库已满");
                                producerLock.wait();
                            }
                        }

                        Thread.sleep(1000);
                        synchronized (queue) {
                            queue.add(num++);
                        }
                        System.out.println("生产一个:" + num);
                        synchronized (consumerLock) {
                            consumerLock.notifyAll();
                        }
                        synchronized (showLock) {
                            showLock.notifyAll();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.err.println("生成线程结束");
            }
        };

        Thread consumerThread = new Thread() {
            @Override
            public void run() {
                int num = 0;
                while (num < maxNum) {
                    try {
                        while (queue.peek() == null && num < maxNum) {
                            synchronized (consumerLock) {
                                consumerLock.wait();
                            }
                        }

                        Thread.sleep(2000);
                        synchronized (queue) {
                            num = queue.poll();
                        }
                        System.out.println("消费一个：" + num);
                        synchronized (producerLock) {
                            producerLock.notifyAll();
                        }
                        synchronized (showLock) {
                            showLock.notifyAll();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.err.println("消费线程结束");
            }
        };

        Thread showThread = new Thread() {
            @Override
            public void run() {
                while(true) {
                    synchronized (showLock) {
                        try {
                            showLock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    synchronized (queue) {
                        String str = "库存列表:";
                        for (int i = 0; i < queue.size(); i++) {
                            int num = queue.get(i);
                            str += num;
                            if (i < queue.size() - 1) {
                                str += ",";
                            }
                        }
                        System.out.println(str);
                    }
                }
            }
        };

        producerThread.start();
        consumerThread.start();

        showThread.setDaemon(true);
        showThread.start();

        producerThread.join();
        consumerThread.join();
        System.out.println("主程序结束");
    }
}


